/** 
    \file context.h
    
    Basic data structure to handle contexts
*/

#ifndef CONTEXTS_H
#define CONTEXTS_H

#include <stdio.h> 
#include "subsets.h"

#define CTX_MAX_JI 1000
#define CTX_MAX_MI 1000

#define CTX_NAME_MAX_LEN 1000
#define CTX_NAME_DIM ((CTX_NAME_MAX_LEN) +1) 



typedef struct context{
    
    char name[CTX_NAME_DIM]; /**< name of the context */
    
    int ji_no; /**< no. join irreducible els  */
    
    char *ji_names[CTX_MAX_JI]; /**< join irreducible els' names */
    
    int mi_no; /**< no. meet irreducible els */
    
    char *mi_names[CTX_MAX_MI]; /**< meet irreducible els' names */
    
    int leq[CTX_MAX_JI][CTX_MAX_MI]; /**< Context matrix */
} Context;

#define FORALLMIIN(mi,context) \
  for((mi)=0; (mi) <context->mi_no; (mi)++)  
#define FORALLJIIN(ji,context) \
  for((ji)=0; (ji) <context->ji_no; (ji)++)  


/* Set the structure */
extern void
ctx_init(Context *, int ji_no, int mi_no);

extern void
ctx_set_name(Context *,char *);

extern void
ctx_set_ji_name(Context *,int,char *);

extern void
ctx_set_mi_name(Context *,int,char *);

extern void
ctx_set_orthogonal(Context *c,int ji,int mi);

/* Free the structure */
extern void
ctx_free(Context *);

/* Read the structure */
extern char *
ctx_name(Context *);

extern char *
ctx_ji_name(Context *,int);

extern char *
ctx_mi_name(Context *,int);

extern int 
ctx_no_ji(Context *);

extern int 
ctx_no_mi(Context *);

extern int
ctx_orthogonal(Context *c,int ji,int mi);

/** Parses a context file from opened file fd.
    See the file context_grammar.y 
*/
extern void
ctx_parse(Context *c,int fd);

/* Operations */


/** \brief Copy of a context 

Pay attention : it does not make a copy of the names !!!
*/

extern void
ctx_cpy(Context *dest, Context *source);


/** \brief frees the space allocated to jis/mis names */
extern void
ctx_del_names(Context *c);

/** \brief Changes a context into its complement */
extern void
ctx_complement(Context *c);

/** \brief Fill a context at random */
extern void
ctx_rand(Context *c);

/* Querying a context */

/**  \brief Returns the index of the join irreducible s  

If s does not belong to the join irreducible els list, we return -1  */
extern int 
ctx_ji_index(Context *c, char *s);

/**  \brief Returns the index of the meet irreducible  s  

If s does not belong to the join irreducible els list, we return -1  */
extern int 
ctx_mi_index(Context *c, char *s);


/* Output */

/**  \brief Prints a context in the format .ctx  
 **     
 Prints a context (to stdout) in the format .ctx  
*/
extern void 
ctx_print(Context *c);

/**  \brief Pretty print of a context to stdout */
extern void 
ctx_print_matrix(Context *c);


extern Subset *
ctx_ji_image(Context *context, int ji);

extern Subset *
ctx_mi_image(Context *context, int mi);

extern Subset *
ctx_mi_closure(Context *context, int mi);

extern Subset *
ctx_ji_closure(Context *context, int ji);


#endif /* CONTEXT_H */
